package app.engine.entitys;

import app.game.enums.Chess;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * @Description 估值模式匹配
 * @Date 2023/6/18 1:00
 * @Created by LYP
 */
public class EvaluationTable {

    private List<EvaluationMode>[] modeList;

    private Integer[] modeCountList;

    public static final int MAX_MODE_LINE = 6;
    public static final int MIN_MODE_LINE = 4;
    public static int modeNum = 0;

    public static final int MAX_SCORE = 9999999;
    public static final int MIN_SCORE = -9999999;

    public EvaluationTable() {
        modeList = new ArrayList[8];
        for (int i = 0; i < modeList.length; i++) {
            modeList[i] = new ArrayList<>();
        }
        EvaluationMode.nextId = 0;
        // 五连  999999分
        modeList[4].add(new EvaluationMode(
                Chess.BLACK_CHESS,
                new Chess[]{Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.BLACK_CHESS},
                new int[]{9999999})
        );
        modeList[4].add(new EvaluationMode(
                Chess.WHITH_CHESS,
                new Chess[]{Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.WHITH_CHESS},
                new int[]{9999999})
        );
        // 活四  10000分
        modeList[5].add(new EvaluationMode(
                2,
                Chess.BLACK_CHESS,
                new Chess[]{Chess.EMPTY, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.EMPTY},
                new int[]{50000, 0})
        );
        modeList[5].add(new EvaluationMode(
                3,
                Chess.WHITH_CHESS,
                new Chess[]{Chess.EMPTY, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.EMPTY},
                new int[]{50000, 0})
        );
        // 冲四  1个200分  2个以上10000分
        modeList[5].add(new EvaluationMode(
                4,
                Chess.BLACK_CHESS,
                new Chess[]{Chess.WHITH_CHESS, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.EMPTY},
                new int[]{1200, 10800, 0})
        );
        modeList[5].add(new EvaluationMode(
                4,
                Chess.BLACK_CHESS,
                new Chess[]{Chess.EMPTY, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.WHITH_CHESS},
                new int[]{1200, 10800, 0})
        );
        modeList[5].add(new EvaluationMode(
                6,
                Chess.BLACK_CHESS,
                new Chess[]{Chess.BLACK_CHESS, Chess.EMPTY, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.EMPTY},
                new int[]{100, 9800, 0})
        );
        modeList[5].add(new EvaluationMode(
                4,
                Chess.BLACK_CHESS,
                new Chess[]{Chess.BLACK_CHESS, Chess.EMPTY, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.WHITH_CHESS},
                new int[]{1200, 10800, 0})
        );
        modeList[4].add(new EvaluationMode(
                4,
                Chess.BLACK_CHESS,
                new Chess[]{Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.EMPTY, Chess.BLACK_CHESS, Chess.BLACK_CHESS},
                new int[]{1200, 10800, 0})
        );
        modeList[5].add(new EvaluationMode(
                6,
                Chess.BLACK_CHESS,
                new Chess[]{Chess.EMPTY, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.EMPTY, Chess.BLACK_CHESS},
                new int[]{200, 9800, 0})
        );
        modeList[5].add(new EvaluationMode(
                4,
                Chess.BLACK_CHESS,
                new Chess[]{Chess.WHITH_CHESS, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.EMPTY, Chess.BLACK_CHESS},
                new int[]{1200, 10800, 0})
        );
        modeList[5].add(new EvaluationMode(
                5,
                Chess.WHITH_CHESS,
                new Chess[]{Chess.BLACK_CHESS, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.EMPTY},
                new int[]{1200, 10800, 0})
        );
        modeList[5].add(new EvaluationMode(
                5,
                Chess.WHITH_CHESS,
                new Chess[]{Chess.EMPTY, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.BLACK_CHESS},
                new int[]{1200, 10800, 0})
        );
        modeList[5].add(new EvaluationMode(
                5,
                Chess.WHITH_CHESS,
                new Chess[]{Chess.WHITH_CHESS, Chess.EMPTY, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.BLACK_CHESS},
                new int[]{1200, 10800, 0})
        );
        modeList[5].add(new EvaluationMode(
                7,
                Chess.WHITH_CHESS,
                new Chess[]{Chess.WHITH_CHESS, Chess.EMPTY, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.EMPTY},
                new int[]{200, 9800, 0})
        );
        modeList[4].add(new EvaluationMode(
                5,
                Chess.WHITH_CHESS,
                new Chess[]{Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.EMPTY, Chess.WHITH_CHESS, Chess.WHITH_CHESS},
                new int[]{1200, 10800, 0})
        );
        modeList[5].add(new EvaluationMode(
                5,
                Chess.WHITH_CHESS,
                new Chess[]{Chess.BLACK_CHESS, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.EMPTY, Chess.WHITH_CHESS},
                new int[]{1200, 10800, 0})
        );
        modeList[5].add(new EvaluationMode(
                7,
                Chess.WHITH_CHESS,
                new Chess[]{Chess.EMPTY, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.EMPTY, Chess.WHITH_CHESS},
                new int[]{200, 9800, 0})
        );
        // 活三  1个100分  2个以上10000分
        modeList[4].add(new EvaluationMode(
                4,
                Chess.BLACK_CHESS,
                new Chess[]{Chess.EMPTY, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.EMPTY},
                new int[]{200, 9800, 0})
        );
        modeList[4].add(new EvaluationMode(
                5,
                Chess.WHITH_CHESS,
                new Chess[]{Chess.EMPTY, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.EMPTY},
                new int[]{200, 9800, 0})
        );
        modeList[5].add(new EvaluationMode(
                4,
                Chess.BLACK_CHESS,
                new Chess[]{Chess.EMPTY, Chess.BLACK_CHESS, Chess.EMPTY, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.EMPTY},
                new int[]{200, 9800, 0})
        );
        modeList[5].add(new EvaluationMode(
                4,
                Chess.BLACK_CHESS,
                new Chess[]{Chess.EMPTY, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.EMPTY, Chess.BLACK_CHESS, Chess.EMPTY},
                new int[]{200, 9800, 0})
        );
        modeList[5].add(new EvaluationMode(
                5,
                Chess.WHITH_CHESS,
                new Chess[]{Chess.EMPTY, Chess.WHITH_CHESS, Chess.EMPTY, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.EMPTY},
                new int[]{200, 9800, 0})
        );
        modeList[5].add(new EvaluationMode(
                5,
                Chess.WHITH_CHESS,
                new Chess[]{Chess.EMPTY, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.EMPTY, Chess.WHITH_CHESS, Chess.EMPTY},
                new int[]{200, 9800, 0})
        );
        // 冲三  每个2分
        modeList[4].add(new EvaluationMode(
                Chess.BLACK_CHESS,
                new Chess[]{Chess.WHITH_CHESS, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.EMPTY},
                new int[]{2})
        );
        modeList[5].add(new EvaluationMode(
                Chess.BLACK_CHESS,
                new Chess[]{Chess.WHITH_CHESS, Chess.BLACK_CHESS, Chess.EMPTY, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.EMPTY},
                new int[]{2})
        );
        modeList[5].add(new EvaluationMode(
                Chess.BLACK_CHESS,
                new Chess[]{Chess.WHITH_CHESS, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.EMPTY, Chess.BLACK_CHESS, Chess.EMPTY},
                new int[]{2})
        );
        modeList[4].add(new EvaluationMode(
                Chess.BLACK_CHESS,
                new Chess[]{Chess.EMPTY, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.WHITH_CHESS},
                new int[]{2})
        );
        modeList[5].add(new EvaluationMode(
                Chess.BLACK_CHESS,
                new Chess[]{Chess.EMPTY, Chess.BLACK_CHESS, Chess.EMPTY, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.WHITH_CHESS},
                new int[]{2})
        );
        modeList[5].add(new EvaluationMode(
                Chess.BLACK_CHESS,
                new Chess[]{Chess.EMPTY, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.EMPTY, Chess.BLACK_CHESS, Chess.WHITH_CHESS},
                new int[]{2})
        );
        modeList[4].add(new EvaluationMode(
                Chess.WHITH_CHESS,
                new Chess[]{Chess.BLACK_CHESS, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.EMPTY},
                new int[]{2})
        );
        modeList[5].add(new EvaluationMode(
                Chess.WHITH_CHESS,
                new Chess[]{Chess.BLACK_CHESS, Chess.WHITH_CHESS, Chess.EMPTY, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.EMPTY},
                new int[]{2})
        );
        modeList[5].add(new EvaluationMode(
                Chess.WHITH_CHESS,
                new Chess[]{Chess.BLACK_CHESS, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.EMPTY, Chess.WHITH_CHESS, Chess.EMPTY},
                new int[]{2})
        );
        modeList[4].add(new EvaluationMode(
                Chess.WHITH_CHESS,
                new Chess[]{Chess.EMPTY, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.BLACK_CHESS},
                new int[]{2})
        );
        modeList[5].add(new EvaluationMode(
                Chess.WHITH_CHESS,
                new Chess[]{Chess.EMPTY, Chess.WHITH_CHESS, Chess.EMPTY, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.BLACK_CHESS},
                new int[]{2})
        );
        modeList[5].add(new EvaluationMode(
                Chess.WHITH_CHESS,
                new Chess[]{Chess.EMPTY, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.EMPTY, Chess.WHITH_CHESS, Chess.BLACK_CHESS},
                new int[]{2})
        );
        // 活二  每个10分
        modeList[3].add(new EvaluationMode(
                Chess.BLACK_CHESS,
                new Chess[]{Chess.EMPTY, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.EMPTY},
                new int[]{10})
        );
        modeList[3].add(new EvaluationMode(
                Chess.WHITH_CHESS,
                new Chess[]{Chess.EMPTY, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.EMPTY},
                new int[]{10})
        );
        modeList[4].add(new EvaluationMode(
                Chess.BLACK_CHESS,
                new Chess[]{Chess.EMPTY, Chess.BLACK_CHESS, Chess.EMPTY, Chess.BLACK_CHESS, Chess.EMPTY},
                new int[]{10})
        );
        modeList[4].add(new EvaluationMode(
                Chess.WHITH_CHESS,
                new Chess[]{Chess.EMPTY, Chess.WHITH_CHESS, Chess.EMPTY, Chess.WHITH_CHESS, Chess.EMPTY},
                new int[]{10})
        );
        // 冲二  每个1分
        modeList[3].add(new EvaluationMode(
                Chess.BLACK_CHESS,
                new Chess[]{Chess.WHITH_CHESS, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.EMPTY},
                new int[]{1})
        );
        modeList[3].add(new EvaluationMode(
                Chess.WHITH_CHESS,
                new Chess[]{Chess.BLACK_CHESS, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.EMPTY},
                new int[]{1})
        );
        modeList[3].add(new EvaluationMode(
                Chess.BLACK_CHESS,
                new Chess[]{Chess.EMPTY, Chess.BLACK_CHESS, Chess.BLACK_CHESS, Chess.WHITH_CHESS},
                new int[]{1})
        );
        modeList[3].add(new EvaluationMode(
                Chess.WHITH_CHESS,
                new Chess[]{Chess.EMPTY, Chess.WHITH_CHESS, Chess.WHITH_CHESS, Chess.BLACK_CHESS},
                new int[]{1})
        );

        modeNum = 0;
        for (int i = 0; i < modeList.length; i++) {
            modeNum += modeList[i].size();
        }

        init();
    }

    public void init() {
        modeCountList = new Integer[EvaluationMode.nextId];
    }

    public int checkChessList(Chess[] chessArray, int length, Chess nowChess) {
        int score = 0;
        List<EvaluationMode> modes = modeList[length];
        for (EvaluationMode evaluationMode: modes) {
            int count = Optional.ofNullable(modeCountList[evaluationMode.id]).orElse(0);
            boolean hit = true;
            for (int i = 0; i <= length; i++) {
                if (!chessArray[i].equals(evaluationMode.pattern[i])) {
                    hit = false;
                }
            }
            if (hit) {
                int hitScore = evaluationMode.values[count >= evaluationMode.values.length ? evaluationMode.values.length - 1 : count];
                //System.out.println(evaluationMode.pChess + "获得评分" + hitScore);
                if (nowChess == evaluationMode.pChess) {
                    score += hitScore;
                } else {
                    if (hitScore > 0) {
                        score -= (hitScore * 1.2);
                    } else if (hitScore > 9999){
                        score -= (hitScore * 2);
                    } else {
                        score -= hitScore;
                    }
                }
                count++;
            }
            modeCountList[evaluationMode.id] = count;
        }
        if (score != 0) {
            //System.out.println(Arrays.toString(chessArray) + "获得评分" + score);
        }
        return score;
    }

}
